<?php

namespace app\services;

use app\traits\Page;
use plugin\admin\app\model\QuestionCategory;
use plugin\admin\app\model\QuestionStore;
use plugin\admin\app\model\ScoreTitle;
use plugin\admin\app\model\UserExamScore;
use plugin\admin\app\model\UserProfile;
use plugin\admin\app\model\UserQuestion;

class QuestionStoreService
{
    public static function categoryList($page = 1, $length = 10)
    {
        $offset = ($page - 1) * $length;
        $query = QuestionCategory::orderByDesc('exam_count');

        $totalCount = (clone $query)->count();
        $categories = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($categories as $key=>$item) {
            $exams = UserExamScore::where('category_id', $item['id'])->get()->toArray();
            $userIds = array_unique(array_column($exams, 'user_id'));
            $userAvatars = UserProfile::select(['avatar'])->whereIn('user_id', $userIds)->get()->toArray();
            $categories[$key]['user_avatars'] = array_column($userAvatars, 'avatar');

            $exam = UserQuestion::where('user_id', get_user_id())->where('category_id', $item['id'])->orderByDesc('created_time')->first();
            $categories[$key]['is_exam'] = boolval($exam);
            $categories[$key]['score'] = $exam['score'] ?? 0;
        }

        return Page::wrap($totalCount, $page, $length, $categories);
    }


    public static function list($categoryId = 0, $length = 10)
    {
        $query = QuestionStore::select(['id', 'category_id', 'type', 'title', 'options', 'answer']);

        if ($categoryId > 0) {
            $query->where('category_id', $categoryId);
        }

        $list = $query->inRandomOrder()->limit($length)->get()->toArray();

        $originalList = $list;

        foreach ($list as $key=>$item) {
            $list[$key]['options'] = json_decode($item['options'], true);
        }

        $examId = UserQuestion::insertGetId([
            'user_id' => get_user_id(),
            'questions' => json_encode($originalList, JSON_UNESCAPED_UNICODE),
            'answers' => '',
            'score' => 0,
            'title' => '',
            'created_time' => date('Y-m-d H:i:s'),
        ]);

        return [$examId, $list];
    }

    public static function rankList($categoryId = 0, $length = 10)
    {
        $userExams = UserExamScore::where('category_id', $categoryId)->orderByDesc('exam_score')->offset(0)->limit($length)->get()->toArray();

        $userIds = array_column($userExams, 'user_id');

        $rank = 0;

        $profiles = UserProfile::select(['user_id', 'nickname', 'avatar'])->whereIn('user_id', $userIds)->get()->toArray();
        $profiles = array_combine(
            array_column($profiles, 'user_id'),
            array_values($profiles)
        );

        foreach ($userExams as $key=>$userExam) {
            $userExams[$key]['rank'] = $key+1;
            $userExams[$key]['user_info'] = $profiles[$userExam['user_id']];

            if ($userExam['user_id'] == get_user_id()) {
                $rank = $key+1;
            }
        }

        if ($rank == 0) {
            $score = UserExamScore::where('user_id', get_user_id())->where('category_id', 1)->first()['exam_score'] ?? 0;
            $rank = UserExamScore::where('category_id', $categoryId)->where('exam_score', '>=', $score)->count() + 1;
        }

        return [$userExams, $rank ?? '无'];
    }

    public static function submit($examId, $answers)
    {
        $exam = UserQuestion::where('id', $examId)->where('user_id', get_user_id())->first();

        if (!$exam) {
            throw new \Exception('考试不存在');
        }

        if ($exam['score'] > 0) {
            throw new \Exception('请勿重复交卷');
        }

        $questions = json_decode($exam['questions'], true);

        $answers = array_combine(
            array_column($answers, 'question_id'),
            array_column($answers, 'answer')
        );

        $score = 0;
        $wrongCount = 0;
        $rightCount = 0;
        $wrongQuestions = [];
        $categoryId = 0;
        foreach ($questions as $key=>$question) {
            $answer = $answers[$question['id']] ?? '';

            $categoryId = $question['category_id'];

            if (strpos($answer, ',') !== false) {
                $questionAnswers = explode(',', $answer);

                $sortAnswers = [];

                foreach ($questionAnswers as $questionAnswer) {
                    $sortAnswers[ord($questionAnswer)] = $questionAnswer;
                }

                sort($sortAnswers);

                $sortAnswers = join(',', array_values($sortAnswers));

                $answer = $sortAnswers;
            }


            if ($answer == $question['answer']) {
                $score += 10;
                $rightCount++;
            } else {
                $wrongCount++;
                $question['wrong_answer'] = $answer;
                $wrongQuestions[] = $question;
            }
        }

        $title = ScoreTitle::where('score', $score)->first();

        $currentTimestamp = time();
        $useTime = $currentTimestamp - strtotime($exam['created_time']);

        $exam->category_id = $categoryId;
        $exam->answers = json_encode($answers, JSON_UNESCAPED_UNICODE);
        $exam->score = $score;
        $exam->wrong_count = $wrongCount;
        $exam->title = $title->title ?? '';
        $exam->right_count = $rightCount;
        $exam->submit_time = date('Y-m-d H:i:s', $currentTimestamp);
        $exam->wrong_questions = json_encode($wrongQuestions, JSON_UNESCAPED_UNICODE);
        $exam->save();

        if (!($examScore = UserExamScore::where('user_id', get_user_id())->where('category_id', $categoryId)->first())) {
            $examScore = new UserExamScore();
            $examScore->user_id = get_user_id();
            $examScore->category_id = $categoryId;
        }

        $examScore->exam_score += $score;

        $examScore->save();

        $profile = UserProfile::where('user_id', get_user_id())->first();

        $profile->exam_count++;
        $profile->exam_score += $score;
        $profile->save();

        QuestionCategory::where('id', $categoryId)->increment('exam_count', 1);

        return ['use_time' => $useTime, 'wrong_count' => $wrongCount, 'right_count' => $rightCount, 'score' => $score, 'wrong_questions' => $wrongQuestions, 'title' => $exam->title];
    }


}